package com.warm.common.doc;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.warm.common.word.Word;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.*;

/**
 * @Description TODO
 * @Author iyb-liangchuang
 * @Date 2021/6/3 14:09
 */
@Slf4j
@Getter
public class Doc {
    private static final String IMAGE_POSTFIX = ".png";
    private static final String RID_PREFIX = "rId00";

    private Config config;
    private TypeEnum type;
    private List<Image> imageList;
    private Map<String, String> imageMap;
    private JSONObject data;
    private String templateDir;

    public Doc(JSONObject data, String templateDir, TypeEnum type){
        this.data = data;
        this.type = type;
        this.config = new Config();
        this.imageList = new ArrayList<>();
        this.imageMap = new HashMap<>();
        this.templateDir = templateDir;
        init(templateDir);

        // 自定义的图片文件：数据格式 {name, data, type}
        if(data.containsKey("handleImgList")){
            handleImage(data.getJSONArray("handleImgList"));
        }
    }

    private void init(String templateDir){
        File dir = new File(templateDir);
        List<String> templateNames = new ArrayList<>();
        File[] templateFiles = dir.listFiles();
        File file = null;
        Image image = null;
        int j = 0;
        for(int i = 0; i < templateFiles.length; i++){
            file = templateFiles[i];
            if(file.getName().endsWith(type.type)){
                config.setSourceFilePath(file.getPath());
                continue;
            } else if(file.getName().endsWith(".xml") || file.getName().endsWith(".rels")){
                templateNames.add(file.getName());
                continue;
            } else if(file.getName().endsWith(".png") || file.getName().endsWith(".jpg") || file.getName().endsWith(".jpeg")){ // 图片
                image = new Image();
                image.setId(RID_PREFIX + j);
                image.setName(file.getName().substring(0, file.getName().lastIndexOf(".")));
                image.setFilename(file.getName());
                image.setData(file.getPath());
                image.setType(Word.ImageType.FILE.getType());
                imageList.add(image);
                imageMap.put(image.getName(), image.getId());
                j += 1;// 保证生成的 RId 唯一、连续
            }
        }
        config.setTemplateFileNames(templateNames);
    }

    private void handleImage(JSONArray handleImgList){
        for(int i = 0; i < handleImgList.size(); i++){
            JSONObject obj = handleImgList.getJSONObject(i);
            // 更新 imageList 里面的数据源
            Optional<Image> first = imageList.stream().filter(image -> obj.getString("name").equals(image.getName())).findFirst();
            Image img = first.isPresent() ? first.get() : new Image();
            img.setData(obj.get("data"));
            img.setType(obj.getString("type"));
            if(img.getId() != null) return;

            // 原始没有的图片源
            img.setName(obj.getString("name"));
            img.setFilename(obj.getString("name") + IMAGE_POSTFIX);
            img.setId(RID_PREFIX + (imageList.size() + 1));
            imageList.add(img);
            imageMap.put(img.getName(), img.getId());
        }
    }

    @Data
    public class Config {
        private String sourceFilePath;// 模板源文件, zip
        private List<String> templateFileNames;// 模板文件名称 需要渲染的文件
    }

    @Data
    public class Image { // 图片媒体文件
        /** doucment.xml.rels 中的图片id配置 */
        private String id;
        /** 图片名称 */
        private String name;
        /** 后缀 */
        private String filename;
        /** 图片文件路径/流 */
        private Object data;
        /** 类型 file-本地文件  url-图片链接 in-inputStream */
        private String type;
    }

    @Getter
    public enum TypeEnum{
        EXCEL(".xlsx"),
        WORD(".docx");

        private String type;
        TypeEnum(String type){
            this.type = type;
        }
    }

    @Getter
    public enum ImageEnum{
        URL("url"),
        FILE("file"),
        STREAM("stream"),
        BASE64("base64"),
        QRCODE("qrcode");

        private String type;
        ImageEnum(String type){
            this.type = type;
        }
    }
}
